/**
 * @description 監聽 DOM 元素的尺寸變化
 */

import { ref, reactive, nextTick, Ref, onBeforeUnmount } from 'vue'
import ResizeObserver from 'resize-observer-polyfill'

interface IReturn {
  // 一個用於綁定DOM元素的ref
  elementRef: Ref<HTMLElement | null>
  // 監聽到DOM變化時,實時的尺寸
  // 尺寸包含 內容,padding,border, 不包括margin
  size: {
    width: number
    height: number
    top: number
    left: number
  }
}

export default function (): IReturn {
  const elementRef = ref<HTMLElement | null>(null)
  const size: IReturn['size'] = reactive({ width: 0, height: 0, top: 0, left: 0 })

  // 這個是用來監聽 DOM 變化的
  const ro = new ResizeObserver(() => {
    // 但是通過這個監聽函數獲取到的DOM的尺寸不包含 padding,border
    // 導致計算的尺寸有偏差
    // 因此使用 getBoundingClientRect 來計算
    if (!elementRef.value) return

    const rect = elementRef.value.getBoundingClientRect()
    size.width = rect.width
    size.height = rect.height
    size.top = rect.top
    size.left = rect.left
  })

  nextTick(() => {
    if (elementRef.value) {
      ro.observe(elementRef.value)
    }
  })

  onBeforeUnmount(() => {
    ro.disconnect()
  })

  return { elementRef, size }
}
